package com.ruogu.codegeneration.controller;

import cn.hutool.core.bean.BeanUtil;
import com.mybatisflex.core.paginate.Page;
import com.ruogu.codegeneration.annotation.AuthCheck;
import com.ruogu.codegeneration.common.BaseResponse;
import com.ruogu.codegeneration.common.DeleteRequest;
import com.ruogu.codegeneration.common.ResultUtils;
import com.ruogu.codegeneration.constant.UserConstant;
import com.ruogu.codegeneration.exception.ErrorCode;
import com.ruogu.codegeneration.exception.ThrowUtils;
import com.ruogu.codegeneration.model.dto.chathistory.ChatHistoryAddRequest;
import com.ruogu.codegeneration.model.dto.chathistory.ChatHistoryQueryRequest;
import com.ruogu.codegeneration.model.entity.App;
import com.ruogu.codegeneration.model.entity.ChatHistory;
import com.ruogu.codegeneration.model.entity.User;
import com.ruogu.codegeneration.model.vo.chathistory.ChatHistoryVO;
import com.ruogu.codegeneration.service.AppService;
import com.ruogu.codegeneration.service.ChatHistoryService;
import com.ruogu.codegeneration.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 对话历史控制层
 *
 * @author ruogu
 */
@RestController
@RequestMapping("/chatHistory")
@Tag(name = "对话历史相关接口-ChatHistoryController")
public class ChatHistoryController {

    @Resource
    private ChatHistoryService chatHistoryService;

    @Resource
    private UserService userService;

    @Resource
    private AppService appService;

    // ------------------------------- 用户相关接口 -------------------------

    /**
     * 创建对话历史
     */
    @PostMapping("/add")
    @Operation(summary = "创建对话历史", description = "用户创建对话历史记录")
    public BaseResponse<Long> addChatHistory(@RequestBody ChatHistoryAddRequest chatHistoryAddRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(chatHistoryAddRequest == null, ErrorCode.PARAMS_ERROR);

        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);

        ChatHistory chatHistory = new ChatHistory();
        BeanUtil.copyProperties(chatHistoryAddRequest, chatHistory);
        chatHistory.setUserId(loginUser.getId());

        // 校验参数
        chatHistoryService.validChatHistory(chatHistory, true);

        // 验证应用权限
        Long appId = chatHistory.getAppId();
        App app = appService.getById(appId);
        ThrowUtils.throwIf(app == null, ErrorCode.NOT_FOUND_ERROR, "应用不存在");

        boolean result = chatHistoryService.save(chatHistory);
        ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(chatHistory.getId());
    }

    /**
     * 根据应用ID获取最新的对话历史
     */
    @GetMapping("/latest")
    @Operation(summary = "获取最新对话历史", description = "根据应用ID获取最新的对话历史，仅应用创建者和管理员可见")
    @Parameters(value = {@Parameter(name = "appId", description = "应用ID", required = true),
            @Parameter(name = "limit", description = "限制条数", required = true),
            @Parameter(name = "lastCreateTime", description = "最后创建时间", required = false)})
    public BaseResponse<Page<ChatHistoryVO>> getLatestChatHistory(@RequestParam Long appId,
                                                                  @RequestParam(defaultValue = "10") int limit,
                                                                  @RequestParam(required = false) LocalDateTime lastCreateTime,
                                                                  HttpServletRequest request) {
        ThrowUtils.throwIf(appId == null || appId <= 0, ErrorCode.PARAMS_ERROR, "应用ID不能为空");
        ThrowUtils.throwIf(limit <= 0 || limit > 50, ErrorCode.PARAMS_ERROR, "限制条数必须在1-50之间");

        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);

        // 验证权限：只有应用创建者和管理员可以查看对话历史
        App app = appService.getById(appId);
        ThrowUtils.throwIf(app == null, ErrorCode.NOT_FOUND_ERROR, "应用不存在");

        // 检查权限
        if (!UserConstant.ADMIN_ROLE.equals(loginUser.getUserRole()) && !app.getUserId().equals(loginUser.getId())) {
            throw new RuntimeException(ErrorCode.NO_AUTH_ERROR.getMessage());
        }

        Page<ChatHistory> chatHistoryPage = chatHistoryService.listAppChatHistoryByPage(appId, limit, lastCreateTime, loginUser);
        List<ChatHistoryVO> chatHistoryVOList = chatHistoryService.getChatHistoryVOList(chatHistoryPage.getRecords());
        return ResultUtils.success(new Page<>(chatHistoryVOList, chatHistoryPage.getPageNumber(), chatHistoryPage.getPageSize(), chatHistoryPage.getTotalRow()));
    }

    /**
     * 删除自己的对话历史
     */
    @PostMapping("/my/delete")
    @Operation(summary = "删除自己的对话历史", description = "用户删除自己的对话历史")
    public BaseResponse<Boolean> deleteMyChatHistory(@RequestBody DeleteRequest deleteRequest, HttpServletRequest request) {
        ThrowUtils.throwIf(deleteRequest == null || deleteRequest.getId() == null || deleteRequest.getId() <= 0,
                ErrorCode.PARAMS_ERROR);

        // 获取当前登录用户
        User loginUser = userService.getLoginUser(request);

        // 获取原对话历史
        ChatHistory oldChatHistory = chatHistoryService.getById(deleteRequest.getId());
        ThrowUtils.throwIf(oldChatHistory == null, ErrorCode.NOT_FOUND_ERROR);

        // 检查权限：只能删除自己的对话历史
        ThrowUtils.throwIf(!oldChatHistory.getUserId().equals(loginUser.getId()), ErrorCode.NO_AUTH_ERROR);

        boolean result = chatHistoryService.removeById(deleteRequest.getId());
        return ResultUtils.success(result);
    }

    // ------------------------------- 管理员相关接口 -------------------------

    /**
     * 根据 id 获取对话历史（管理员）
     */
    @GetMapping("/get")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @Operation(summary = "根据ID获取对话历史", description = "管理员根据对话历史ID获取详细信息")
    public BaseResponse<ChatHistory> getChatHistoryById(long id) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        ChatHistory chatHistory = chatHistoryService.getById(id);
        ThrowUtils.throwIf(chatHistory == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(chatHistory);
    }

    /**
     * 根据 id 获取对话历史VO（管理员）
     */
    @GetMapping("/get/vo")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @Operation(summary = "根据ID获取对话历史VO", description = "管理员根据对话历史ID获取详细信息")
    public BaseResponse<ChatHistoryVO> getChatHistoryVoById(long id) {
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);
        ChatHistory chatHistory = chatHistoryService.getById(id);
        ThrowUtils.throwIf(chatHistory == null, ErrorCode.NOT_FOUND_ERROR);
        return ResultUtils.success(chatHistoryService.getChatHistoryVO(chatHistory));
    }

    /**
     * 删除对话历史（管理员）
     */
    @PostMapping("/delete")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @Operation(summary = "删除对话历史", description = "管理员根据对话历史ID删除记录")
    public BaseResponse<Boolean> deleteChatHistory(@RequestBody DeleteRequest deleteRequest) {
        ThrowUtils.throwIf(deleteRequest == null || deleteRequest.getId() == null || deleteRequest.getId() <= 0,
                ErrorCode.PARAMS_ERROR);
        boolean result = chatHistoryService.removeById(deleteRequest.getId());
        return ResultUtils.success(result);
    }

    /**
     * 分页获取所有对话历史（管理员）
     */
    @PostMapping("/list/page/vo/admin")
    @AuthCheck(mustRole = UserConstant.ADMIN_ROLE)
    @Operation(summary = "分页获取所有对话历史", description = "管理员分页获取所有对话历史，用于内容监管")
    public BaseResponse<Page<ChatHistoryVO>> listChatHistoryVoByPageAdmin(@RequestBody ChatHistoryQueryRequest chatHistoryQueryRequest) {
        ThrowUtils.throwIf(chatHistoryQueryRequest == null, ErrorCode.PARAMS_ERROR);

        long pageNum = chatHistoryQueryRequest.getPageNum();
        long pageSize = chatHistoryQueryRequest.getPageSize();

        Page<ChatHistory> chatHistoryPage = chatHistoryService.page(
                Page.of(pageNum, pageSize),
                chatHistoryService.getQueryWrapper(chatHistoryQueryRequest)
        );

        Page<ChatHistoryVO> chatHistoryVoPage = new Page<>(pageNum, pageSize, chatHistoryPage.getTotalRow());
        List<ChatHistoryVO> chatHistoryVOList = chatHistoryService.getChatHistoryVOList(chatHistoryPage.getRecords());
        chatHistoryVoPage.setRecords(chatHistoryVOList);
        return ResultUtils.success(chatHistoryVoPage);
    }
}